# wip

import os, sys, json
import http.client

def resolve_fname(arg):
    '''以某种约定寻找配置文件
    '''
    fnames = [arg, 'setup-' + arg]
    prefix = ['', 'setup-']
    suffix = ['config', 'json']
    for fname in ['%s%s.%s' % (p, arg, s) for p in prefix for s in suffix]:
        if os.path.isfile(fname):
            return fname
    raise FileNotFoundError

def reg():
    if len(sys.argv) > 1:
        fd = open(resolve_fname(sys.argv[1]))
    else:
        fd = open('setup-dev.config')
    config = fd.read()
    fd.close()
    config = json.loads(config)
    host = config["consul_host"]
    port = config["consul_port"]

    client = ConsulClient(host, port)
    if len(sys.argv) > 2:
        matcher = lambda x : x["Name"] == sys.argv[2]
    else:
        matcher = lambda x : True
    for serv in config["services"]:
        if matcher(serv):
            client.register_service(**serv)

def de_reg(service_name):
    # read config
    fd = open(resolve_fname(service_name))
    config = fd.read()
    fd.close()

    config = json.loads(config)
    host = config["consul_host"]
    port = config["consul_port"]

    conn = http.client.HTTPConnection(host, port)
    headers = {}
    headers["Content-Type"] = "application/json"
    conn.request("PUT", "/v1/agent/service/deregister/" + sys.argv[2], headers = headers)
    resp = conn.getresponse()
    print(resp.status, str(resp.read(), 'utf8'))

class ConsulClient:

    def __init__(self, host, port):
        self._host = host
        self._port = port
        self._headers = {}
        self._headers["Content-Type"] = "application/json"

    def _is_ok(self, resp):
        return resp.status > 199 and resp.status < 300

    def register_service(self, name = None, address = None, port = 8500, **serv_config):
        body = {
            "Name": name,
            "Address": address,
            "Port": port
        }
        for k, v in serv_config.items():
            body[k.title()] = v
        body = bytes(json.dumps(body), 'utf8')
        conn = http.client.HTTPConnection(self._host, self._port)
        try:
            conn.request('PUT', "/v1/agent/service/register?replace-existing-checks=true", body = body, headers = self._headers)
            resp = conn.getresponse()
            return self._is_ok(resp)
        finally:
            conn.close()

    def get_services(self):
        conn = http.client.HTTPConnection(self._host, self._port)
        try:
            conn.request('GET', '/v1/agent/services', headers = self._headers)
            resp = conn.getresponse()
            if not self._is_ok(resp):
                return None
            resp = resp.read()
            return json.loads(resp)
        finally:
            conn.close()
